package com.ruoyi.module.service;


import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.module.bo.QtysBo;
import com.ruoyi.module.bo.SkuStock;
import com.ruoyi.module.bo.StockUpdateBo;
import com.ruoyi.module.client.OpendjClient;
import com.ruoyi.module.domain.JdToken;
import com.ruoyi.module.dto.RetDTO;
import com.ruoyi.module.dto.SkuMainDTO;
import com.ruoyi.module.dto.StockCenterDTO;
import com.ruoyi.module.dto.WebResponseDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @since 2019/4/23 17:02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OpendjService {
    private final OpendjClient opendjClient;

    /**
     * 根据商家商品编码和商家门店编码批量修改现货库存接口
     *
     * @param skuStockList
     * @return
     */
    public String batchUpdateCurrentQtys(List<SkuStock> skuStockList, JdToken jdToken) {
        String results;
        try {
            String token = jdToken.getToken();
            // 商家门店编码
            String outStationNo = jdToken.getOutStationNo();
            // 到家门店编码
            String stationNo = jdToken.getStationNo();
            String userPin = jdToken.getUid();
            String appKey = jdToken.getAppKey();
            String appSecret = jdToken.getAppSecret();

            if (skuStockList.size() > 10000) {
                QtysBo bo = new QtysBo();
                //bo.setOutStationNo(outStationNo);
                bo.setStationNo(stationNo);
                bo.setUserPin(userPin);
                // 每次只能处理50个
                AtomicReference<String> result = new AtomicReference<>("");

                ListUtil.split(skuStockList, 50).forEach(list -> {
                    bo.setSkuStockList(list);

                    WebResponseDTO<?> webResponse = opendjClient.batchUpdateCurrentQtys(appKey, appSecret, token, bo);
                    String response = JSON.toJSONString(webResponse);
                    log.info("batchUpdateCurrentQtys result:{}", response);
                    result.set(result.get() + response);
                });

                results = result.get();
            } else {
                StockUpdateBo bo = new StockUpdateBo();
                bo.setStationNo(stationNo);
                StringBuilder result = new StringBuilder();
                for (SkuStock skuStock : skuStockList) {
                    String outSkuId = skuStock.getOutSkuId();
                    bo.setSkuId(outSkuId);

                    Integer stockQty = skuStock.getStockQty();
                    bo.setCurrentQty(stockQty);

                    WebResponseDTO<?> webResponse = opendjClient.updateStock(appKey, appSecret, token, bo);

                    String arg = JSON.toJSONString(webResponse);
                    log.info("updateStock result:{}", arg);
                    result.append(arg);
                }
                results = result.toString();
            }
        } catch (Exception e) {
            log.error("同步京东到家库存异常", e);
            results = e.getMessage();
        }
        return results;
    }

    /**
     * 根据商家商品编码和商家门店编码批量修改现货库存接口
     *
     * @param skuStockList
     * @return
     */
    private Map<String, StockCenterDTO> queryStockCenter(List<SkuStock> skuStockList, JdToken jdToken) {
        try {
            String token = jdToken.getToken();
            // 商家门店编码
            String outStationNo = jdToken.getOutStationNo();
            // 到家门店编码
            String stationNo = jdToken.getStationNo();
            String userPin = jdToken.getUid();
            String appKey = jdToken.getAppKey();
            String appSecret = jdToken.getAppSecret();

            // 商品信息，最多50条
            Map<String, Object> bo = new HashMap<>();
            bo.put("outStationNo", stationNo);
            //bo.put("stationNo", stationNo);
            bo.put("userPin", userPin);
            // 每次只能处理50个
            Map<String, StockCenterDTO> result = new HashMap<>();
            ListUtil.split(skuStockList, 50).forEach(list -> {
                bo.put("skuIds", list);

                WebResponseDTO<?> webResponse = opendjClient.queryStockCenter(appKey, appSecret, token, bo);
                log.info("queryStockCenter result:{}", JSON.toJSONString(webResponse));
                if (webResponse.isSuccess()) {
                    String data = String.valueOf(webResponse.getData());
                    if (StringUtils.isNotEmpty(data)) {

                        RetDTO<Map<String, String>> retDTO = JSON.parseObject(data, RetDTO.class);

                        String retData = JSON.toJSONString(retDTO.getData());

                        List<StockCenterDTO> stockList = JSON.parseArray(retData, StockCenterDTO.class);
                        for (StockCenterDTO stockCenterDTO : stockList) {
                            if (0 == stockCenterDTO.getCode()) {
                                result.put(stockCenterDTO.getOutSkuId(), stockCenterDTO);
                            }
                        }
                    }
                }
            });
            return result;
        } catch (Exception e) {
            log.error("同步京东到家库存异常", e);
        }
        return null;
    }

    public List<String> queryOutSkuIds(JdToken jdToken, int pageNo) {
        List<SkuMainDTO> skuMainDTOS = this.querySkuinfos(jdToken, pageNo);

        if (CollectionUtils.isNotEmpty(skuMainDTOS)) {
            return skuMainDTOS.stream().map(SkuMainDTO::getOutSkuId).distinct().collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 查询商家已上传商品信息列表接口
     *
     * @return
     */
    public List<SkuMainDTO> querySkuinfos(JdToken jdToken, int pageNo) {
        try {
            String token = jdToken.getToken();
            // 商家门店编码
            String outStationNo = jdToken.getOutStationNo();
            // 到家门店编码
            String stationNo = jdToken.getStationNo();
            String userPin = jdToken.getUid();
            String appKey = jdToken.getAppKey();
            String appSecret = jdToken.getAppSecret();

            // 商品信息，最多20条
            Map<String, Object> bo = new HashMap<>();
            bo.put("pageNo", String.valueOf(pageNo));
            bo.put("pageSize", String.valueOf(50));
            bo.put("isFilterDel", "0");

            WebResponseDTO<?> webResponse = opendjClient.querySkuInfos(appKey, appSecret, token, bo);

            log.info("querySkuInfos result:{}", JSON.toJSONString(webResponse));
            if (webResponse.isSuccess()) {
                String data = String.valueOf(webResponse.getData());
                if (StringUtils.isNotEmpty(data)) {
                    Map<String, Object> retDTO = JSON.parseObject(data, Map.class);

                    retDTO = (Map<String, Object>) retDTO.get("result");

                    return JSON.parseArray(String.valueOf(retDTO.get("result")), SkuMainDTO.class);
                }
            }
        } catch (Exception e) {
            log.error("同步京东到家库存异常", e);
        }
        return null;
    }


    /**
     * 根据到家商品编码批量更新商家商品编码接口
     *
     * @return
     */
    public Boolean batchUpdateOutSkuId(JdToken jdToken, List<Map<String, Object>> skuInfoList) {
        try {
            String token = jdToken.getToken();
            String appKey = jdToken.getAppKey();
            String appSecret = jdToken.getAppSecret();

            Map<String, Object> param = new HashMap<>();
            param.put("skuInfoList", JSON.toJSONString(skuInfoList));

            WebResponseDTO<?> webResponse = opendjClient.batchUpdateOutSkuId(appKey, appSecret, token, param);

            log.info("batchUpdateOutSkuId result:{}", JSON.toJSONString(webResponse));
            if (webResponse.isSuccess()) {
                return Boolean.TRUE;
            }
        } catch (Exception e) {
            log.error("同步京东到家库存异常", e);
        }
        return Boolean.FALSE;
    }
}
